package test;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.FilenameFilter;
import java.io.IOException;
import java.io.LineNumberReader;
import java.sql.SQLException;
import java.text.DecimalFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.List;

import org.apache.log4j.Logger;

import com.brother.alarm.AlarmObserverImpl;
import com.brother.database.DataBase;
import com.brother.geocode.GeoCoder;
import com.brother.ibatis.ClientFactory;
import com.brother.model.AlarmType;
import com.brother.model.LatLngAddress;
import com.brother.model.RealTimeData;
import com.brother.model.Report;
import com.brother.model.Signal;
import com.brother.model.Tracker;
import com.brother.realtime.AlarmEmailSender;
import com.brother.realtime.Command;
import com.brother.realtime.DataCommand;
import com.brother.realtime.MutilDataCommand;
import com.brother.service.RealDataService;
import com.brother.service.ReportService;
import com.brother.service.TrackerService;
import com.brother.util.CommonProperties;
import com.brother.util.KenyaAddress;
import com.brother.util.LatLngConverter;
import com.brother.util.MalaysiaAddress;
import com.brother.util.NigeriaAddress;
import com.brother.util.TanzaniaAddress;
import com.ibatis.sqlmap.client.SqlMapClient;

public class ParseDataFromLog {

	private static FileOutputStream out = null;  
	
	/**
	 * @param args
	 * @throws IOException 
	 * @throws ParseException 
	 * @throws IOException 
	 */
	public static void main(String[] args) throws IOException{
		out = new FileOutputStream("./backup.log", true);
		out.write(("started date "+(new Date())+"\r\n").getBytes());
		try {
			start(args);
		} catch (ParseException e) {
			Logger.getLogger(ParseDataFromLog.class).error("",e);
		} catch (IOException e) {
			Logger.getLogger(ParseDataFromLog.class).error("",e);
		}
		out.close();
	}
	
	public static void start(String[] args) throws ParseException, IOException {
		out.write((args[1]+"  "+args[2]).getBytes());
		final SimpleDateFormat sd = new SimpleDateFormat("yyyy-MM-dd");
		final Date start = sd.parse(args[1]);
		final Date end = sd.parse(args[2]);
		List<String> imeis = new ArrayList<String>();
		imeis.add("353451040271841");
//		imeis.add("353451041604362");
//		imeis.add("353451040779314");
//		imeis.add("353451040777961");
//		imeis.add("353451041164847");
//		imeis.add("353451041165570");
//		imeis.add("353451040541912");
//		imeis.add("353451041164052");
//		imeis.add("353451041174481");
//		imeis.add("353451041669787");
//		
//		imeis.add("353451041635697");
//		imeis.add("353451041649615");
//		imeis.add("353451041673813");
//		imeis.add("353451041166818");
//		imeis.add("353451041669605");
//		imeis.add("353451041647601");
//		
//		imeis.add("353451041160027");
//		imeis.add("353451041669670");
		String path = args[0];
		File file = new File(path);
		CommandParser parser = new CommandParser();
		File[] files =file.listFiles(new FilenameFilter() {
			
			@Override
			public boolean accept(File dir, String name) {
				if(name.indexOf("log.txt.") > -1){
					name = name.substring(name.indexOf("log.txt.")+"log.txt.".length());
					if(name.indexOf("-")>-1){
						try {
							Date date = sd.parse(name);
							if(date.after(start) && date.before(end)){
								return true;
							}
						} catch (ParseException e) {
							e.printStackTrace();
						}
					}
					
					
				}
				return false;
			}
		});
		Arrays.sort(files, new Comparator<File>(){

			@Override
			public int compare(File arg0, File arg1) {
				String name = arg0.getName();
				name = name.substring(name.indexOf("log.txt.")+"log.txt.".length());
				Date d1 = null;
				if(name.indexOf("-")>-1){
					try {
						d1 = sd.parse(name);
					} catch (ParseException e) {
						e.printStackTrace();
					}
				}
				name = arg1.getName();
				name = name.substring(name.indexOf("log.txt.")+"log.txt.".length());
				Date d2 = null;
				if(name.indexOf("-")>-1){
					try {
						d2 = sd.parse(name);
					} catch (ParseException e) {
						e.printStackTrace();
					}
				}
				if(d1.before(d2)){
					return -1;
				}
				return 1;
			}
		});
		if(files.length > 0){
			for(File f : files){
				out.write(("file:"+f.getName()+"\r\n").getBytes());
			}
		}
		int startPos = 0;
		StringBuffer sb = new StringBuffer();
		for(File f : files){
			out.write(("parsing file "+f.getName()+"\r\n").getBytes());
			LineNumberReader in = new LineNumberReader(new FileReader(f)); 
			String line = "";
			while((line = in.readLine()) != null){
				startPos = line.indexOf(",parse command:");
				if( startPos > -1){
					String imei = line.substring(0, startPos);
					imei = imei.substring(imei.lastIndexOf(",")+1);
					if(!imeis.contains(imei)){
						continue;
					}
					startPos = startPos+",parse command:".length();
					String cmdStr = line.substring(startPos);
					sb.delete(0, sb.length());
					sb.append(cmdStr);
					Command command = parser.readOneCommand(sb);
					if(command instanceof DataCommand){
						Tracker tracker = tks.getTrackerByFieldName("userTrackerId", imei);
						if(tracker == null){
							out.write(("no tracker for "+imei+"\r\n").getBytes());
							continue;
						}
						saveRealtimeData((DataCommand)command, tracker);
					}else if(command instanceof MutilDataCommand){
						Tracker tracker = tks.getTrackerByFieldName("userTrackerId", imei);
						if(tracker == null){
							out.write(("no tracker for "+imei+"\r\n").getBytes());
							continue;
						}
						for(DataCommand c : ((MutilDataCommand)command).getCommands()){
							saveRealtimeData(c, tracker);
						}
					}
					
				}
			}
			DataBase.closeThreadConnection();
			in.close();
		}
	}
	
	static private TrackerService tks = new TrackerService();
	private static void saveRealtimeData(DataCommand cmd, Tracker tracker) throws IOException {
		out.write(("insert report ,trackerid="+tracker.getUserTrackerId()+"\r\n").getBytes());
		RealDataService rs = new RealDataService();
		
		AlarmObserverImpl alo = new AlarmObserverImpl();
		
		final RealTimeData data = new RealTimeData();
		
		data.setOrient(cmd.getOrient());
		data.setAlarmObserver(alo);
		DecimalFormat nf1 =new DecimalFormat("00");
		data.setOrig_lat(nf1.format((int)Math.abs(cmd.getLat())) + Float.toString(Math.abs(LatLngConverter.toFen(cmd.getLat()))));
		data.setLatOrient(cmd.getLatOrient());
		data.setLat(cmd.getLat());
		DecimalFormat nf =new DecimalFormat("000");
		
		data.setOrig_lng(nf.format(Math.abs((int)Math.abs(cmd.getLng())))+Float.toString(Math.abs(LatLngConverter.toFen(cmd.getLng()))));
		data.setLng(cmd.getLng());
		data.setLngOrient(cmd.getLngOrient());
		
		data.setTrackerid(tracker.getTrackerid());
		data.setState(cmd.getFlag());
		data.setSignal(Signal.ok.name());
		data.setSpeed(cmd.getSpeed());
		
		data.setDistance("0");
		data.setTraceDateTime(cmd.getDate());
		data.setLanguage("en");
		
		data.ckeckTriggerredAlarm();
		if(data.getState().equalsIgnoreCase(AlarmType.GPS_Pos.name())){
			data.setState(cmd.getFlag());
		}
		if(data.getState().equalsIgnoreCase(AlarmType.GPS_Pos.name())){
			data.setState("");
		}
		
		/*Tracker tker = null;
		if(this.tracker != null && this.tracker.getMileUpdate() != null){
			tker = this.tks.getTrackerByFieldName("trackerId", this.tracker.getTrackerid());
			float mileage = tker.getMileage();
			LatLngPoint from = new LatLngPoint();
	        int lngSign = data.getLngOrient().equals("W") ? -1 : 1;
	        int latSign = data.getLatOrient().equals("S") ? -1 : 1;
			from.setLat(data.getLat()*latSign);
			from.setLng(data.getLng()*lngSign);
			
			LatLngPoint to = new LatLngPoint();
			List<RealTimeData> rl = new ArrayList();
			rs.isConnected(tracker.getTrackerid() , rl);
			if(rl.size() > 0){
				lngSign = rl.get(0).getLngOrient().equals("W") ? -1 : 1;
		        latSign = rl.get(0).getLatOrient().equals("S") ? -1 : 1;
				to.setLat(rl.get(0).getLat()*latSign);
				to.setLng(rl.get(0).getLng()*lngSign);
				mileage = (float) (mileage + Distance.distance(from, to)/1000);
				tks.setMileage(this.tracker.getTrackerid(), mileage);
			}
		}*/
		if(cmd.getAccStat() != null){
			tks.updateAccStatus(tracker.getTrackerid(), ""+cmd.getAccStat());
		}
		if(cmd.getDoorStat() != null){
			tks.updateDoorStatus(tracker.getTrackerid(), ""+cmd.getDoorStat());
		}
		rs.insertData(data);
		/*if(tker == null){
			this.updateMileage(Signal.ok);
		}*/
	}
	
	static ReportService reportSrv = new  ReportService();
	/**首先是否已经符合条件时间间隔，插入一条报告信息
	 * @param data
	 * @throws IOException 
	 */
	private static void insertReport(RealTimeData data) throws IOException {
		out.write(("insert report address="+data.getAddress()+",trackerid="+data.getTrackerid()).getBytes());
		LatLngAddress addr = GeoCoder.getAddress((data.getLatOrient().equals("S")? -data.getLat(): data.getLat())+"",
				(data.getLngOrient().equals("W")? -data.getLng():data.getLng())+"", data.getLanguage());
		if(addr != null){
			data.setAddress(addr.getAddress());
		}else{
	        int lngSign = data.getLngOrient().equals("W") ? -1 : 1;
	        int latSign = data.getLatOrient().equals("S") ? -1 : 1;
	        String address = null;
	        if(NigeriaAddress.getInstance().isIntesect(data.getLat()*latSign, data.getLng()*lngSign))
	        	address = NigeriaAddress.getInstance().getAddressByDB(data.getLat()*latSign, data.getLng()*lngSign);
	        else if(MalaysiaAddress.getInstance().isIntesect(data.getLat()*latSign, data.getLng()*lngSign)){
	        	address = MalaysiaAddress.getInstance().getAddressByDB(data.getLat()*latSign, data.getLng()*lngSign);
	        }else if(KenyaAddress.getInstance().isIntesect(data.getLat()*latSign, data.getLng()*lngSign)){
	        	address = KenyaAddress.getInstance().getAddressByDB(data.getLat()*latSign, data.getLng()*lngSign);
	        }else if(TanzaniaAddress.getInstance().isIntesect(data.getLat()*latSign, data.getLng()*lngSign)){
	        	address = TanzaniaAddress.getInstance().getAddressByDB(data.getLat()*latSign, data.getLng()*lngSign);
	        }
	        if(address != null){
	        	data.setAddress(address);
	        	GeoCoder.saveAddress((data.getLat()*latSign) + "", (data.getLng()*lngSign)+ "", address, "en", null,null);
	        }
		}
		
		//System.out.println("insert report data:" + data.getAddress());
		TrackerService tks = new TrackerService();
		Tracker tracker = tks.getTrackerByFieldName("trackerid", data.getTrackerid());
		
		SqlMapClient map = ClientFactory.getSqlMapper();
		Report report = new Report();
		report.setOrderCondition(" order by r.createTime desc");
		report.setTopCondition(" limit 0,1");
		report.setTrackerid(data.getTrackerid());
		try {
				report.setTrackerid(data.getTrackerid());
				report.setCreateTime(data.getTraceDateTime());
				report.setAddress(data.getAddress());
				report.setComment(data.getComment());
				report.setLat(data.getLat());
				report.setLng(data.getLng());
				if(data.getLatOrient().equals("S")){
					report.setSignedLat(-Math.abs(data.getLat()));
				}else{
					report.setSignedLat(data.getLat());
				}
				if(data.getLngOrient().equals("W")){
					report.setSignedLng(-Math.abs(data.getLng()));
				}else{
					report.setSignedLng(data.getLng());
				}
				report.setOrig_lat(data.getOrig_lat());
				report.setOrig_lng(data.getOrig_lng());
				report.setLatOrient(data.getLatOrient());
				report.setLngOrient(data.getLngOrient());
				report.setOrient(data.getOrient());
				report.setSignal(data.getSignal());
				report.setState(data.getState());
				report.setSpeed(data.getSpeed());
				report.setLanguage(data.getLanguage());
				report.setRealTimedataId(data.getRealTimedataId());
				
				report.setBattery(data.getBattery());
				report.setVoltage(data.getVoltage());
				report.setFuel(data.getFuel());
				report.setFlag(data.getFlag());
				report.setAd2(data.getAd2());
				report.setTemp(data.getTemp());
				
				if(report.getAddress() == null){
					//LatLngAddress addr = GeoCoder.getAddress(data.getLat()+"", data.getLng()+"", data.getLanguage());
					//System.out.println("set address in insertData insert report  858888888888888888888888"+addr);
					//report.setAddress(addr == null ? null: addr.getAddress());
				}
				//map.insert("insertReport",report);
				reportSrv.insertData(report, tracker);
		} catch (Exception e) {
			Logger.getLogger(ParseDataFromLog.class).error("",e);
		}finally{
			try {
				map.endTransaction();
			} catch (SQLException e) {
				Logger.getLogger(ParseDataFromLog.class).error("", e);
			}
		}
	}

	
	/**根据imei号创建一个历史数据的表格
	 * @param userTrackerId
	 */
	private static boolean createTable(String imei) {
		try{
			/*CREATE TABLE `report` (
			  `reportId` int(11) NOT NULL AUTO_INCREMENT,
			  `trackerId` varchar(50) DEFAULT NULL,
			  `address` varchar(130) DEFAULT NULL,
			  `createTime` datetime DEFAULT NULL,
			  `orig_lat` varchar(20) DEFAULT NULL,
			  `lat` float(8,6) DEFAULT '0.000000',
			  `lng` float(9,6) DEFAULT '0.000000',
			  `latOrient` varchar(5) DEFAULT 'N',
			  `lngOrient` varchar(5) DEFAULT 'W',
			  `orig_lng` varchar(20) DEFAULT NULL,
			  `speed` float(10,5) DEFAULT '0.00000',
			  `orient` varchar(10) DEFAULT '0',
			  `state` varchar(20) DEFAULT NULL,
			  `signal` varchar(10) DEFAULT 'ok',
			  `language` varchar(10) DEFAULT 'zh_CN',
			  `signed_lat` float(8,6) DEFAULT NULL,
			  `signed_lng` float(9,6) DEFAULT NULL,
			  PRIMARY KEY (`reportId`),
			  KEY `createTime` (`trackerId`),
			) ENGINE=MyISAM DEFAULT CHARSET=utf8*/
			String sql = CommonProperties.getReportTableSchema().replaceFirst("\\{imei\\}", imei);
			out.write(("creating table "+sql+"\r\n").getBytes());
			if(DataBase.update(sql) != -1){
				return true;
			}
		}catch(Exception e){
			Logger.getLogger(ParseDataFromLog.class).error(e);
		}finally{
			DataBase.closeConnection();
		}
		return false;
	}
	
	/**检查是否具有相应的数据表，每个跟踪器一个数据表
	 * @param imei
	 * @return
	 */
	private static boolean hasTable(String imei){
		try{
			String sql = "select * from r_"+imei+" limit 0,1";
			DataBase.query(sql).next();
			return true;
		}catch(Exception e){
			if(e.getMessage().indexOf("doesn't exist") > -1){
				return false;
			}
		}finally{
			DataBase.closeConnection();
		}
		return false;
	}
	
}
